package org.road0329.dlt698.axdr;

import org.road0329.dlt698.ReverseByteArrayInputStream;
import org.road0329.dlt698.ReverseByteArrayOutputStream;
import org.road0329.dlt698.asn1.axdr.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Data extends AxdrType {
    private static Logger logger = LoggerFactory.getLogger(Data.class);
    private byte[] dataCode = null;
    private Choice choice = Choice._ERR_NONE_SELECTED;
    private AxdrNull nullData = null;
    private DataSequence array = null;
    private DataSequence structure = null;
    private AxdrBoolean bool = null;
    private AxdrBitString bitString = null;
    private Integer32 doubleLong = null;
    private Unsigned32 doubleLongUnsigned = null;
    private AxdrOctetString octetString = null;
    private AxdrOctetString visibleString = null;
    private AxdrOctetString utf8String = null;
    private Integer8 integer = null;
    private Integer16 longdata = null;
    private Unsigned8 unsigned = null;
    private Unsigned16 longUnsigned = null;
    private Integer64 long64 = null;
    private Unsigned64 long64Unsigned = null;
    private AxdrEnum enumdata = null;
    private Float32 float32 = null;
    private Float64 float64 = null;
    private DateTime dateTime = null;
    private Date date = null;
    private Time time = null;
    private DateTimeS dateTimeS = null;
    private Unsigned16 oi = null;
    private OAD oad = null;
    private ROAD road = null;
    private OMD omd = null;
    private TI ti = null;
    private TSA tsa = null;
    private MAC mac = null;
    private RN rn = null;
    private Region region = null;
    private ScalerUnit scalerUnit = null;
    private RSD rsd = null;
    private CSD csd = null;
    private MS ms = null;
    private SID sid = null;
    private SIDMAC sidMac = null;
    private COMDCB comdcb = null;
    private RCSD rcsd = null;
    private AxdrNull dontCare = null;

    public Data() {
    }

    public void setDataCode(byte[] dataCode) {
        this.dataCode = dataCode;
    }

    public int decode(ReverseByteArrayInputStream input) throws Exception {
        int codeLength = 0;
        AxdrEnum choosen = new AxdrEnum();
        choosen.setConst();
        codeLength += choosen.decode(input);
        resetChoices();
        choice = Choice.getEnumByValue((int) choosen.getValue());
        if (choice == Choice.NULL_DATA) {
            nullData = new AxdrNull();
            codeLength += nullData.decode(input);

        } else if (choice == Choice.ARRAY) {
            array = new DataSequence();
            codeLength += array.decode(input);

        } else if (choice == Choice.STRUCTURE) {
            structure = new DataSequence();
            codeLength += structure.decode(input);

        } else if (choice == Choice.BOOL) {
            bool = new AxdrBoolean();
            codeLength += bool.decode(input);

        } else if (choice == Choice.BIT_STRING) {
            bitString = new AxdrBitString();
            codeLength += bitString.decode(input);

        } else if (choice == Choice.DOUBLE_LONG) {
            doubleLong = new Integer32();
            doubleLong.setConst();
            codeLength += doubleLong.decode(input);

        } else if (choice == Choice.DOUBLE_LONG_UNSIGNED) {
            doubleLongUnsigned = new Unsigned32();
            doubleLongUnsigned.setConst();
            codeLength += doubleLongUnsigned.decode(input);

        } else if (choice == Choice.OCTET_STRING) {
            octetString = new AxdrOctetString();
            codeLength += octetString.decode(input);

        } else if (choice == Choice.VISIBLE_STRING) {
            visibleString = new AxdrOctetString();
            codeLength += visibleString.decode(input);

        } else if (choice == Choice.UTF8_STRING) {
            utf8String = new AxdrOctetString();
            codeLength += utf8String.decode(input);

        } else if (choice == Choice.INTEGER) {
            integer = new Integer8();
            integer.setConst();
            codeLength += integer.decode(input);

        } else if (choice == Choice.LONGDATA) {
            longdata = new Integer16();
            longdata.setConst();
            codeLength += longdata.decode(input);

        } else if (choice == Choice.UNSIGNED) {
            unsigned = new Unsigned8();
            unsigned.setConst();
            codeLength += unsigned.decode(input);

        } else if (choice == Choice.LONG_UNSIGNED) {
            longUnsigned = new Unsigned16();
            longUnsigned.setConst();
            codeLength += longUnsigned.decode(input);

        } else if (choice == Choice.LONG64) {
            long64 = new Integer64();
            long64.setConst();
            codeLength += long64.decode(input);

        } else if (choice == Choice.LONG64_UNSIGNED) {
            long64Unsigned = new Unsigned64();
            long64Unsigned.setConst();
            codeLength += long64Unsigned.decode(input);

        } else if (choice == Choice.ENUMDATA) {
            enumdata = new AxdrEnum();
            enumdata.setConst();
            codeLength += enumdata.decode(input);

        } else if (choice == Choice.FLOAT32) {
            float32 = new Float32();
            codeLength += float32.decode(input);

        } else if (choice == Choice.FLOAT64) {
            float64 = new Float64();
            codeLength += float64.decode(input);

        } else if (choice == Choice.DATE_TIME) {
            dateTime = new DateTime();
            codeLength += dateTime.decode(input);

        } else if (choice == Choice.DATE) {
            date = new Date();
            codeLength += date.decode(input);

        } else if (choice == Choice.TIME) {
            time = new Time();
            codeLength += time.decode(input);

        } else if (choice == Choice.DATE_TIME_S) {
            dateTimeS = new DateTimeS();
            codeLength += dateTimeS.decode(input);

        } else if (choice == Choice.OI) {
            oi = new Unsigned16();
            oi.setConst();
            codeLength += oi.decode(input);

        } else if (choice == Choice.OAD) {
            oad = new OAD();
            codeLength += oad.decode(input);

        } else if (choice == Choice.ROAD) {
            road = new ROAD();
            codeLength += road.decode(input);

        } else if (choice == Choice.OMD) {
            omd = new OMD();
            codeLength += omd.decode(input);

        } else if (choice == Choice.TI) {
            ti = new TI();
            codeLength += ti.decode(input);

        } else if (choice == Choice.TSA) {
            tsa = new TSA();
            codeLength += tsa.decode(input);

        } else if (choice == Choice.MAC) {
            mac = new MAC();
            codeLength += mac.decode(input);

        } else if (choice == Choice.RN) {
            rn = new RN();
            codeLength += rn.decode(input);

        } else if (choice == Choice.REGION) {
            region = new Region();
            codeLength += region.decode(input);

        } else if (choice == Choice.SCALER_UNIT) {
            scalerUnit = new ScalerUnit();
            codeLength += scalerUnit.decode(input);

        } else if (choice == Choice.RSD) {
            rsd = new RSD();
            codeLength += rsd.decode(input);

        } else if (choice == Choice.CSD) {
            csd = new CSD();
            codeLength += csd.decode(input);

        } else if (choice == Choice.MS) {
            ms = new MS();
            codeLength += ms.decode(input);

        } else if (choice == Choice.SID) {
            sid = new SID();
            codeLength += sid.decode(input);

        } else if (choice == Choice.SID_MAC) {
            sidMac = new SIDMAC();
            codeLength += sidMac.decode(input);

        } else if (choice == Choice.COMDCB) {
            comdcb = new COMDCB();
            codeLength += comdcb.decode(input);

        } else if (choice == Choice.RCSD) {
            rcsd = new RCSD();
            codeLength += rcsd.decode(input);

        } else if (choice == Choice.DONT_CARE) {
            dontCare = new AxdrNull();
            codeLength += dontCare.decode(input);

        } else {
            throw new Exception("Error decoding AxdrChoice: Identifier matched to no item.");
        }
        logger.debug("Data.decode: choice = {}", choice);
        return codeLength;
    }


    public int encode(ReverseByteArrayOutputStream output) throws Exception {
        if (dataCode != null) {
            for (int i = dataCode.length - 1; i >= 0; i--) {
                output.write(dataCode[i]);
            }
            return dataCode.length;
        }
        if (choice == Choice._ERR_NONE_SELECTED) {
            throw new Exception("Error encoding AxdrChoice: No item in choice was selected.");
        }
        int codeLength = 0;
        if (choice == Choice.DONT_CARE) {
            codeLength += dontCare.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(255);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.RCSD) {
            codeLength += rcsd.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(96);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.COMDCB) {
            codeLength += comdcb.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(95);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.SID_MAC) {
            codeLength += sidMac.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(94);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.SID) {
            codeLength += sid.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(93);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.MS) {
            codeLength += ms.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(92);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.CSD) {
            codeLength += csd.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(91);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.RSD) {
            codeLength += rsd.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(90);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.SCALER_UNIT) {
            codeLength += scalerUnit.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(89);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.REGION) {
            codeLength += region.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(88);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.RN) {
            codeLength += rn.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(87);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.MAC) {
            codeLength += mac.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(86);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.TSA) {
            codeLength += tsa.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(85);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.TI) {
            codeLength += ti.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(84);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.OMD) {
            codeLength += omd.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(83);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.ROAD) {
            codeLength += road.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(82);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.OAD) {
            codeLength += oad.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(81);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.OI) {
            codeLength += oi.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(80);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.DATE_TIME_S) {
            codeLength += dateTimeS.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(28);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.TIME) {
            codeLength += time.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(27);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.DATE) {
            codeLength += date.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(26);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.DATE_TIME) {
            codeLength += dateTime.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(25);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.FLOAT64) {
            codeLength += float64.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(24);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.FLOAT32) {
            codeLength += float32.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(23);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.ENUMDATA) {
            codeLength += enumdata.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(22);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.LONG64_UNSIGNED) {
            codeLength += long64Unsigned.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(21);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.LONG64) {
            codeLength += long64.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(20);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.LONG_UNSIGNED) {
            codeLength += longUnsigned.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(18);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.UNSIGNED) {
            codeLength += unsigned.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(17);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.LONGDATA) {
            codeLength += longdata.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(16);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.INTEGER) {
            codeLength += integer.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(15);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.UTF8_STRING) {
            codeLength += utf8String.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(12);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.VISIBLE_STRING) {
            codeLength += visibleString.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(10);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.OCTET_STRING) {
            codeLength += octetString.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(9);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.DOUBLE_LONG_UNSIGNED) {
            codeLength += doubleLongUnsigned.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(6);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.DOUBLE_LONG) {
            codeLength += doubleLong.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(5);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.BIT_STRING) {
            codeLength += bitString.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(4);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.BOOL) {
            codeLength += bool.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(3);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.STRUCTURE) {
            codeLength += structure.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(2);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.ARRAY) {
            codeLength += array.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(1);
            codeLength += c.encode(output);
            return codeLength;
        }
        if (choice == Choice.NULL_DATA) {
            codeLength += nullData.encode(output);
            AxdrEnum c = new AxdrEnum();
            c.setMinMaxVal(0);
            codeLength += c.encode(output);
            return codeLength;
        }
        throw new Exception("Error encoding AxdrChoice: No item in choice was encoded.");
    }

    public void encodeAndSave(int encodingSizeGuess) throws Exception {
        ReverseByteArrayOutputStream revOStream = new ReverseByteArrayOutputStream();
        revOStream.setBufSize(encodingSizeGuess);
        encode(revOStream);
        dataCode = revOStream.getArray();
    }

    public Choice getChoiceIndex() {
        return choice;
    }

    public void resetChoices() {
        choice = Choice._ERR_NONE_SELECTED;
        nullData = null;
        array = null;
        structure = null;
        bool = null;
        bitString = null;
        doubleLong = null;
        doubleLongUnsigned = null;
        octetString = null;
        visibleString = null;
        utf8String = null;
        integer = null;
        longdata = null;
        unsigned = null;
        longUnsigned = null;
        long64 = null;
        long64Unsigned = null;
        enumdata = null;
        float32 = null;
        float64 = null;
        dateTime = null;
        date = null;
        time = null;
        dateTimeS = null;
        oi = null;
        oad = null;
        road = null;
        omd = null;
        ti = null;
        tsa = null;
        mac = null;
        rn = null;
        region = null;
        scalerUnit = null;
        rsd = null;
        csd = null;
        ms = null;
        sid = null;
        sidMac = null;
        comdcb = null;
        rcsd = null;
        dontCare = null;
    }

    public Choice getChoice() {
        return choice;
    }

    public AxdrNull getNullData() {
        return nullData;
    }

    public DataSequence getArray() {
        return array;
    }

    public DataSequence getStructure() {
        return structure;
    }

    public AxdrBoolean getBool() {
        return bool;
    }

    public AxdrBitString getBitString() {
        return bitString;
    }

    public Integer32 getDoubleLong() {
        return doubleLong;
    }

    public Unsigned32 getDoubleLongUnsigned() {
        return doubleLongUnsigned;
    }

    public AxdrOctetString getOctetString() {
        return octetString;
    }

    public AxdrOctetString getVisibleString() {
        return visibleString;
    }

    public AxdrOctetString getUtf8String() {
        return utf8String;
    }

    public Integer8 getInteger() {
        return integer;
    }

    public Integer16 getLongdata() {
        return longdata;
    }

    public Unsigned8 getUnsigned() {
        return unsigned;
    }

    public Unsigned16 getLongUnsigned() {
        return longUnsigned;
    }

    public Integer64 getLong64() {
        return long64;
    }

    public Unsigned64 getLong64Unsigned() {
        return long64Unsigned;
    }

    public AxdrEnum getEnumdata() {
        return enumdata;
    }

    public Float32 getFloat32() {
        return float32;
    }

    public Float64 getFloat64() {
        return float64;
    }

    public DateTime getDateTime() {
        return dateTime;
    }

    public Date getDate() {
        return date;
    }

    public Time getTime() {
        return time;
    }

    public DateTimeS getDateTimeS() {
        return dateTimeS;
    }

    public Unsigned16 getOi() {
        return oi;
    }

    public OAD getOad() {
        return oad;
    }

    public ROAD getRoad() {
        return road;
    }

    public OMD getOmd() {
        return omd;
    }

    public TI getTi() {
        return ti;
    }

    public TSA getTsa() {
        return tsa;
    }

    public MAC getMac() {
        return mac;
    }

    public RN getRn() {
        return rn;
    }

    public Region getRegion() {
        return region;
    }

    public ScalerUnit getScalerUnit() {
        return scalerUnit;
    }

    public RSD getRsd() {
        return rsd;
    }

    public CSD getCsd() {
        return csd;
    }

    public MS getMs() {
        return ms;
    }

    public SID getSid() {
        return sid;
    }

    public SIDMAC getSidMac() {
        return sidMac;
    }

    public COMDCB getComdcb() {
        return comdcb;
    }

    public RCSD getRcsd() {
        return rcsd;
    }

    public AxdrNull getDontCare() {
        return dontCare;
    }

    public void setNullData(AxdrNull null_data) {
        resetChoices();
        choice = Choice.NULL_DATA;
        this.nullData = null_data;
    }

    public void setArray(DataSequence array) {
        resetChoices();
        choice = Choice.ARRAY;
        this.array = array;
    }

    public void setStructure(DataSequence structure) {
        resetChoices();
        choice = Choice.STRUCTURE;
        this.structure = structure;
    }

    public void setBool(AxdrBoolean bool) {
        resetChoices();
        choice = Choice.BOOL;
        this.bool = bool;
    }

    public void setBitString(AxdrBitString bit_string) {
        resetChoices();
        choice = Choice.BIT_STRING;
        this.bitString = bit_string;
    }

    public void setDoubleLong(Integer32 double_long) {
        resetChoices();
        choice = Choice.DOUBLE_LONG;
        this.doubleLong = double_long;
    }

    public void setDoubleLongUnsigned(Unsigned32 double_long_unsigned) {
        resetChoices();
        choice = Choice.DOUBLE_LONG_UNSIGNED;
        this.doubleLongUnsigned = double_long_unsigned;
    }

    public void setOctString(AxdrOctetString octet_string) {
        resetChoices();
        choice = Choice.OCTET_STRING;
        this.octetString = octet_string;
    }

    public void setVisibleString(AxdrOctetString visible_string) {
        resetChoices();
        choice = Choice.VISIBLE_STRING;
        this.visibleString = visible_string;
    }

    public void setUtf8String(AxdrOctetString utf8_string) {
        resetChoices();
        choice = Choice.UTF8_STRING;
        this.utf8String = utf8_string;
    }

    public void setInteger(Integer8 integer) {
        resetChoices();
        choice = Choice.INTEGER;
        this.integer = integer;
    }

    public void setLongData(Integer16 long_data) {
        resetChoices();
        choice = Choice.LONGDATA;
        this.longdata = long_data;
    }

    public void setUnsigned(Unsigned8 unsigned) {
        resetChoices();
        choice = Choice.UNSIGNED;
        this.unsigned = unsigned;
    }

    public void setLongUnsigned(Unsigned16 long_unsigned) {
        resetChoices();
        choice = Choice.LONG_UNSIGNED;
        this.longUnsigned = long_unsigned;
    }

    public void setLong64(Integer64 long64) {
        resetChoices();
        choice = Choice.LONG64;
        this.long64 = long64;
    }

    public void setLong64Unsigned(Unsigned64 long64_unsigned) {
        resetChoices();
        choice = Choice.LONG64_UNSIGNED;
        this.long64Unsigned = long64_unsigned;
    }

    public void setEnumData(AxdrEnum enumdata) {
        resetChoices();
        choice = Choice.ENUMDATA;
        this.enumdata = enumdata;
    }

    public void setFloat32(Float32 float32) {
        resetChoices();
        choice = Choice.FLOAT32;
        this.float32 = float32;
    }

    public void setFloat64(Float64 float64) {
        resetChoices();
        choice = Choice.FLOAT64;
        this.float64 = float64;
    }

    public void setDateTime(DateTime date_time) {
        resetChoices();
        choice = Choice.DATE_TIME;
        this.dateTime = date_time;
    }

    public void setDate(Date date) {
        resetChoices();
        choice = Choice.DATE;
        this.date = date;
    }

    public void setTime(Time time) {
        resetChoices();
        choice = Choice.TIME;
        this.time = time;
    }

    public void setDateTimes(DateTimeS date_time_s) {
        resetChoices();
        choice = Choice.DATE_TIME_S;
        this.dateTimeS = date_time_s;
    }

    public void setOi(Unsigned16 oi) {
        resetChoices();
        choice = Choice.OI;
        this.oi = oi;
    }

    public void setOad(OAD oad) {
        resetChoices();
        choice = Choice.OAD;
        this.oad = oad;
    }

    public void setRoad(ROAD road) {
        resetChoices();
        choice = Choice.ROAD;
        this.road = road;
    }

    public void setOmd(OMD omd) {
        resetChoices();
        choice = Choice.OMD;
        this.omd = omd;
    }

    public void setTi(TI ti) {
        resetChoices();
        choice = Choice.TI;
        this.ti = ti;
    }

    public void setTsa(TSA tsa) {
        resetChoices();
        choice = Choice.TSA;
        this.tsa = tsa;
    }

    public void setMac(MAC mac) {
        resetChoices();
        choice = Choice.MAC;
        this.mac = mac;
    }

    public void setRn(RN rn) {
        resetChoices();
        choice = Choice.RN;
        this.rn = rn;
    }

    public void setRegion(Region region) {
        resetChoices();
        choice = Choice.REGION;
        this.region = region;
    }

    public void setScalerUnit(ScalerUnit scaler_unit) {
        resetChoices();
        choice = Choice.SCALER_UNIT;
        this.scalerUnit = scaler_unit;
    }

    public void setRsd(RSD rsd) {
        resetChoices();
        choice = Choice.RSD;
        this.rsd = rsd;
    }

    public void setCsd(CSD csd) {
        resetChoices();
        choice = Choice.CSD;
        this.csd = csd;
    }

    public void setMs(MS ms) {
        resetChoices();
        choice = Choice.MS;
        this.ms = ms;
    }

    public void setSid(SID sid) {
        resetChoices();
        choice = Choice.SID;
        this.sid = sid;
    }

    public void setSidMac(SIDMAC sid_mac) {
        resetChoices();
        choice = Choice.SID_MAC;
        this.sidMac = sid_mac;
    }

    public void setComdcb(COMDCB comdcb) {
        resetChoices();
        choice = Choice.COMDCB;
        this.comdcb = comdcb;
    }

    public void setRcsd(RCSD rcsd) {
        resetChoices();
        choice = Choice.RCSD;
        this.rcsd = rcsd;
    }

    public void set_dontCare(AxdrNull dont_care) {
        resetChoices();
        choice = Choice.DONT_CARE;
        this.dontCare = dont_care;
    }

    @Override
    public String toString() {
        if (choice == Choice.NULL_DATA) {
            if (nullData != null) {
                return "choice: {null_data: " + nullData + "}";
            } else {
                return "choice is null_data but null_data is null";
            }
        } else if (choice == Choice.ARRAY) {
            if (array != null) {
                return "choice: {array: " + array + "}";
            } else {
                return "choice is array but array is null";
            }
        } else if (choice == Choice.STRUCTURE) {
            if (structure != null) {
                return "choice: {structure: " + structure + "}";
            } else {
                return "choice is structure but structure is null";
            }
        } else if (choice == Choice.BOOL) {
            if (bool != null) {
                return "choice: {bool: " + bool + "}";
            } else {
                return "choice is bool but bool is null";
            }
        } else if (choice == Choice.BIT_STRING) {
            if (bitString != null) {
                return "choice: {bit_string: " + bitString + "}";
            } else {
                return "choice is bit_string but bit_string is null";
            }
        } else if (choice == Choice.DOUBLE_LONG) {
            if (doubleLong != null) {
                return "choice: {double_long: " + doubleLong + "}";
            } else {
                return "choice is double_long but double_long is null";
            }
        } else if (choice == Choice.DOUBLE_LONG_UNSIGNED) {
            if (doubleLongUnsigned != null) {
                return "choice: {double_long_unsigned: " + doubleLongUnsigned + "}";
            } else {
                return "choice is double_long_unsigned but double_long_unsigned is null";
            }
        } else if (choice == Choice.OCTET_STRING) {
            if (octetString != null) {
                return "choice: {octet_string: " + octetString + "}";
            } else {
                return "choice is octet_string but octet_string is null";
            }
        } else if (choice == Choice.VISIBLE_STRING) {
            if (visibleString != null) {
                return "choice: {visible_string: " + visibleString + "}";
            } else {
                return "choice is visible_string but visible_string is null";
            }
        } else if (choice == Choice.UTF8_STRING) {
            if (utf8String != null) {
                return "choice: {utf8_string: " + utf8String + "}";
            } else {
                return "choice is utf8_string but utf8_string is null";
            }
        } else if (choice == Choice.INTEGER) {
            if (integer != null) {
                return "choice: {integer: " + integer + "}";
            } else {
                return "choice is integer but integer is null";
            }
        } else if (choice == Choice.LONGDATA) {
            if (longdata != null) {
                return "choice: {longdata: " + longdata + "}";
            } else {
                return "choice is longdata but longdata is null";
            }
        } else if (choice == Choice.UNSIGNED) {
            if (unsigned != null) {
                return "choice: {unsigned: " + unsigned + "}";
            } else {
                return "choice is unsigned but unsigned is null";
            }
        } else if (choice == Choice.LONG_UNSIGNED) {
            if (longUnsigned != null) {
                return "choice: {long_unsigned: " + longUnsigned + "}";
            } else {
                return "choice is long_unsigned but long_unsigned is null";
            }
        } else if (choice == Choice.LONG64) {
            if (long64 != null) {
                return "choice: {long64: " + long64 + "}";
            } else {
                return "choice is long64 but long64 is null";
            }
        } else if (choice == Choice.LONG64_UNSIGNED) {
            if (long64Unsigned != null) {
                return "choice: {long64_unsigned: " + long64Unsigned + "}";
            } else {
                return "choice is long64_unsigned but long64_unsigned is null";
            }
        } else if (choice == Choice.ENUMDATA) {
            if (enumdata != null) {
                return "choice: {enumdata: " + enumdata + "}";
            } else {
                return "choice is enumdata but enumdata is null";
            }
        } else if (choice == Choice.FLOAT32) {
            if (float32 != null) {
                return "choice: {float32: " + float32 + "}";
            } else {
                return "choice is float32 but float32 is null";
            }
        } else if (choice == Choice.FLOAT64) {
            if (float64 != null) {
                return "choice: {float64: " + float64 + "}";
            } else {
                return "choice is float64 but float64 is null";
            }
        } else if (choice == Choice.DATE_TIME) {
            if (dateTime != null) {
                return "choice: {date_time: " + dateTime + "}";
            } else {
                return "choice is date_time but date_time is null";
            }
        } else if (choice == Choice.DATE) {
            if (date != null) {
                return "choice: {date: " + date + "}";
            } else {
                return "choice is date but date is null";
            }
        } else if (choice == Choice.TIME) {
            if (time != null) {
                return "choice: {time: " + time + "}";
            } else {
                return "choice is time but time is null";
            }
        } else if (choice == Choice.DATE_TIME_S) {
            if (dateTimeS != null) {
                return "choice: {date_time_s: " + dateTimeS + "}";
            } else {
                return "choice is date_time_s but date_time_s is null";
            }
        } else if (choice == Choice.OI) {
            if (oi != null) {
                return "choice: {oi: " + oi + "}";
            } else {
                return "choice is oi but oi is null";
            }
        } else if (choice == Choice.OAD) {
            if (oad != null) {
                return "choice: {oad: " + oad + "}";
            } else {
                return "choice is oad but oad is null";
            }
        } else if (choice == Choice.ROAD) {
            if (road != null) {
                return "choice: {road: " + road + "}";
            } else {
                return "choice is road but road is null";
            }
        } else if (choice == Choice.OMD) {
            if (omd != null) {
                return "choice: {omd: " + omd + "}";
            } else {
                return "choice is omd but omd null";
            }
        } else if (choice == Choice.TI) {
            if (ti != null) {
                return "choice: {ti: " + ti + "}";
            } else {
                return "choice is ti but oi null";
            }
        } else if (choice == Choice.TSA) {
            if (tsa != null) {
                return "choice: {tsa: " + tsa + "}";
            } else {
                return "choice is tsa but tsa null";
            }
        } else if (choice == Choice.MAC) {
            if (mac != null) {
                return "choice: {mac: " + mac + "}";
            } else {
                return "choice is mac but mac  null";
            }
        } else if (choice == Choice.RN) {
            if (rn != null) {
                return "choice: {rn: " + rn + "}";
            } else {
                return "choice is rn but rn null";
            }
        } else if (choice == Choice.REGION) {
            if (region != null) {
                return "choice: {region: " + region + "}";
            } else {
                return "choice is region but region null";
            }
        } else if (choice == Choice.SCALER_UNIT) {
            if (scalerUnit != null) {
                return "choice: {scaler_unit: " + scalerUnit + "}";
            } else {
                return "choice is scaler_unit but scaler_unit null";
            }
        } else if (choice == Choice.RSD) {
            if (rsd != null) {
                return "choice: {rsd: " + rsd + "}";
            } else {
                return "choice is rsd but rsd null";
            }
        } else if (choice == Choice.CSD) {
            if (csd != null) {
                return "choice: {csd: " + csd + "}";
            } else {
                return "choice is csd but csd null";
            }
        } else if (choice == Choice.MS) {
            if (ms != null) {
                return "choice: {ms: " + ms + "}";
            } else {
                return "choice is ms but ms null";
            }
        } else if (choice == Choice.SID) {
            if (sid != null) {
                return "choice: {sid: " + sid + "}";
            } else {
                return "choice is sid but sid null";
            }
        } else if (choice == Choice.SID_MAC) {
            if (sidMac != null) {
                return "choice: {sid_mac: " + sidMac + "}";
            } else {
                return "choice is sid_mac but sid_mac null";
            }
        } else if (choice == Choice.COMDCB) {
            if (comdcb != null) {
                return "choice: {comdcb: " + comdcb + "}";
            } else {
                return "choice is comdcb but comdcb null";
            }
        } else if (choice == Choice.RCSD) {
            if (rcsd != null) {
                return "choice: {rcsd: " + rcsd + "}";
            } else {
                return "choice is rcsd but rcsd null";
            }
        } else if (choice == Choice.DONT_CARE) {
            if (dontCare != null) {
                return "choice: {dont_care: " + dontCare + "}";
            } else {
                return "choice is dont_care but dont_care null";
            }
        } else {
            return "unknown";
        }
    }

    public enum Choice {
        _ERR_NONE_SELECTED(-1),
        NULL_DATA(0),
        ARRAY(1),
        STRUCTURE(2),
        BOOL(3),
        BIT_STRING(4),
        DOUBLE_LONG(5),
        DOUBLE_LONG_UNSIGNED(6),
        OCTET_STRING(9),
        VISIBLE_STRING(10),
        UTF8_STRING(12),
        INTEGER(15),
        LONGDATA(16),
        UNSIGNED(17),
        LONG_UNSIGNED(18),
        LONG64(20),
        LONG64_UNSIGNED(21),
        ENUMDATA(22),
        FLOAT32(23),
        FLOAT64(24),
        DATE_TIME(25),
        DATE(26),
        TIME(27),
        DATE_TIME_S(28),
        OI(80),
        OAD(81),
        ROAD(82),
        OMD(83),
        TI(84),
        TSA(85),
        MAC(86),
        RN(87),
        REGION(88),
        SCALER_UNIT(89),
        RSD(90),
        CSD(91),
        MS(92),
        SID(93),
        SID_MAC(94),
        COMDCB(95),
        RCSD(96),
        DONT_CARE(255);

        private final int value;

        private Choice(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public static Choice getEnumByValue(int value) {
            for (Choice item : Choice.values()) {
                if (value == item.getValue()) {
                    return item;
                }
            }
            return null;
        }
    }
}



